package org.goldenport.g3

import scala.xml.Node
import com.asamioffice.goldenport.io.UURL
import org.goldenport.g3.atom._
import org.goldenport.g3.events.Getted

/**
 * @since   Mar. 19, 2010
 * @version Oct.  5, 2010
 * @author  ASAMI, Tomoharu
 */
abstract class G3Adapter extends G3Contextable with G3Actionable {
  private lazy val parcel_title = getClass.getSimpleName

  def parcelTitle = parcel_title

  def open(ctx: G3Context) {
    setContext(ctx)
    open_Adapter()
  }

  protected def open_Adapter() {
  }

  def close() {
    close_Adapter()
  }

  protected def close_Adapter() {
  }

  def execute(parcel: G3Parcel): G3Parcel = {
    log_enter("execute", parcel.content)
    val result = execute_action(parcel)
    log_leave("execute", result.content)
    result
  }
}

object NullAdapter extends G3Adapter {
  override def parcelTitle = "Nop"

  override def execute(parcel: G3Parcel): G3Parcel = parcel

  override def do_Action(parcel: G3Parcel) = parcel
}

class AgentAdapter(val activity: PartialFunction[AnyRef, AnyRef]) extends G3Adapter with ActivityActionable {
  override def parcelTitle = "Agent"

  def create_Activity(ctx: G3AgentContext) = activity

/*
  override protected def do_Action(parcel: G3Parcel, ctx: G3AgentContext): (Any, List[Any]) = {
    (do_action(activity)(parcel, ctx), parcel.attachments)
  }
*/

//  override protected def doAction(content: Any): Any = activity(content)
}

/*
trait AgentAction extends G3Actionable with DoActionActivity {
  protected final def do_action00(activity: PartialFunction[Any, Any])(parcel: G3Parcel): G3Parcel = {
    val result = activity(parcel.content)
    post_action(parcel, result)
  }

  protected final def do_action0(activity: PartialFunction[Any, Any])(parcel: G3Parcel): G3Parcel = {
    val result = if (activity.isDefinedAt(parcel)) {
      activity(parcel)
    } else if (activity.isDefinedAt(parcel.content)) {
      activity(parcel.content)
    } else {
      activity(parcel.content)
    }
    post_action(parcel, result)
  }
}
*/

class Agent2Adapter(val activity: G3AgentContext => PartialFunction[AnyRef, AnyRef]) extends G3Adapter with ActivityActionable {
  override def parcelTitle = "Agent2"

  def create_Activity(ctx: G3AgentContext) = activity(ctx)
}

class BeanAdapter(val className: String, val methodName: Option[String]) extends G3Adapter {

  val parcel_title = "Bean[" + className + (methodName match {
    case Some(name) => "." + name
    case None => ""
  }) + "]"
  override def parcelTitle = parcel_title

  override protected def do_Action(content: AnyRef, parcel: G3Parcel, ctx: G3AgentContext): AnyRef = {
    val args: Array[AnyRef] = content match {
      case array: Array[AnyRef] => array
/*
      case _ => content match {
        case v: Byte => Array(new runtime.RichByte(v))
        case v: Short => Array(new runtime.RichShort(v))
        case v: Int => Array(new runtime.RichInt(v))
        case v: Char => Array(new runtime.RichChar(v))
        case v: Long => Array(new runtime.RichLong(v))
        case v: Float => Array(new runtime.RichFloat(v))
        case v: Double => Array(new runtime.RichDouble(v))
        case _ => Array(content.asInstanceOf[AnyRef])
      }
*/
      case seq: Seq[AnyRef] => seq.toArray
      case _ => Array(content)
    }
    context.invokeBean(className, methodName, args)
  }
}

class ComponentAdapter(val component: G3Component) extends G3Adapter {
  val parcel_title = "Component[" + component.name + "]"
  override def parcelTitle = parcel_title

  override protected def do_Action(parcel: G3Parcel) = {
    component.action(parcel)
  }
}

class ServiceAdapter(val uri: String) extends G3Adapter {
  val parcel_title = "Service[" + uri + "]"
  override def parcelTitle = parcel_title

  val url = UURL.getURLFromFileOrURLName(uri)
  val encoding = "utf-8"

  override protected def do_Action(content: AnyRef, parcel: G3Parcel, ctx: G3AgentContext) = {
    ctx.urlFetchString(url, encoding)
  }
}
